[C/C++] Trie字典樹實作

Trie是一種特殊的樹狀結構,在用於字串處理的時候相當有用,是一種空間換取時間的結構。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include <iostream>
#include <vector>
using namespace std;
class Node {
private:
char content ;
bool mark ;
vector<Node*> children;
public:
Node();
~Node();
char getContent();
void setContent(char c);
bool isMark();
void setMark(bool b);
Node* findChild(char c);
void appendChild(Node* child);
vector<Node*> getChildren();
};
Node::Node(){
content = ' ';
mark = false ;
}
Node::~Node(){
}
char Node::getContent(){
return content ;
}
void Node::setContent(char c){
content = c ;
}
bool Node::isMark(){
return mark ;
}
void Node::setMark(bool b){
mark = b ;
}
Node* Node::findChild(char c)
{
for ( int i = 0; i < children.size(); i++ ){
Node* temp = children.at(i);
if ( temp->getContent() == c ){
return temp;
}
}
return NULL;
}
void Node::appendChild(Node* child){
children.push_back(child);
}
vector<Node*> Node::getChildren(){
return children;
}
class Trie {
public:
Trie();
~Trie();
void addWord(string s);
bool searchWord(string s);
void deleteWord(string s);
private:
Node* root;
};
Trie::Trie(){
root = new Node() ;
}
Trie::~Trie(){
}
void Trie::addWord(string s)
{
Node* current = root ;
if ( s.length() == 0 ){
current->setMark(true);
return;
}
for ( int i = 0; i < s.length(); i++ ){
Node* child = current->findChild(s[i]);
if ( child != NULL ){
current = child;
}
else{
Node* tmp = new Node();
tmp->setContent(s[i]);
current->appendChild(tmp);
current = tmp;
}
if ( i == s.length() - 1 ){
current->setMark(true);
}
}
}
bool Trie::searchWord(string s)
{
Node* current = root;
while ( current != NULL ){
for ( int i = 0; i < s.length(); i++ ){
Node* tmp = current->findChild(s[i]);
if ( tmp == NULL )
return false;
current = tmp;
}
if ( current->isMark() )
return true;
else
return false;
}
return false;
}
void Trie::deleteWord(string s)
{
Node* current = root ;
while ( current != NULL ){
for ( int i = 0; i < s.length(); i++ ){
Node* tmp = current->findChild(s[i]);
if ( tmp == NULL )
return ;
current = tmp;
}
if ( current->isMark() )
current->setMark(false);
else
return ;
}
return ;
}
int main()
{
Trie* trie = new Trie();
trie->addWord("Jeno5980515");
if ( trie->searchWord("Jeno5980515") )
cout << "Yes Jeno5980515" << endl ;
else
cout << "No Jeno5980515" << endl ;
if ( trie->searchWord("Jeno") )
cout << "Yes Jeno" << endl ;
else
cout << "No Jeno" << endl ;
if ( trie->searchWord("5980515") )
cout << "Yes 5980515" << endl ;
else
cout << "No 5980515" << endl ;
trie->deleteWord("Jeno5980515");
if ( trie->searchWord("Jeno5980515") )
cout << "Yes Jeno5980515" << endl ;
else
cout << "No Jeno5980515" << endl ;
if ( trie->searchWord("Jeno") )
cout << "Yes Jeno" << endl ;
else
cout << "No Jeno" << endl ;
if ( trie->searchWord("5980515") )
cout << "Yes 5980515" << endl ;
else
cout << "No 5980515" << endl ;
delete trie;
return 0 ;
}

參考

C++ Tries ~ Programming Tutorials by SourceTricks